from contextlib import contextmanager
from datetime import datetime

from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
from sqlalchemy import text
from sqlalchemy.dialects.mysql import TINYINT, BIGINT, VARCHAR, DATETIME


class SQLAlchemy(_SQLAlchemy):
    """
    Transaction Context Manager
    """

    @contextmanager
    def trans(self):
        try:
            yield
            self.session.commit()
        except Exception as e:
            self.session.rollback()
            raise e


# register sqlalchemy
db = SQLAlchemy()


class BaseModel(db.Model):
    __abstract__ = True
    created_at = db.Column(DATETIME, comment='创建时间', server_default=text('Now()'))
    updated_at = db.Column(DATETIME, comment='更新时间', server_default=text('Now()'), onupdate=datetime.now())
    is_deleted = db.Column(TINYINT, comment='是否逻辑删除', server_default=text('0'), index=True)

    @classmethod
    def queryset(cls):
        """
        Data that is not logically deleted
        """
        return cls.query.filter(cls.is_deleted == 0)


class UserInfo(BaseModel):
    __tablename__ = 'user_info'

    id = db.Column(BIGINT, primary_key=True)
    username = db.Column(VARCHAR(60), comment='用户名', server_default='')
    password = db.Column(VARCHAR(60), comment='密码', server_default='')
    nickname = db.Column(VARCHAR(255), comment='昵称', server_default='')


class TokenBlockList(BaseModel):
    __tablename__ = 'token_block'

    id = db.Column(BIGINT, primary_key=True)
    jti = db.Column(VARCHAR(36), server_default='', comment='Secret')
